#include "bitmap.h"
#include "stdlib.h"
#include "stdio.h"

BitMap::BitMap()
{
}

void BitMap::initialize(char *bitmap, const int length)
{
    this->bitmap = bitmap;
    this->length = length;

    int bytes = ceil(length, 8);

    for (int i = 0; i < bytes; ++i)
    {
        bitmap[i] = 0;
    }
}

bool BitMap::get(const int index) const
{
    int pos = index / 8;
    int offset = index % 8;

    return (bitmap[pos] & (1 << offset));
}

void BitMap::set(const int index, const bool status)
{
    int pos = index / 8;
    int offset = index % 8;

    // 清0
    bitmap[pos] = bitmap[pos] & (~(1 << offset));

    // 置1
    if (status)
    {
        bitmap[pos] = bitmap[pos] | (1 << offset);
    }
}

int BitMap::allocate(const int count)
{
    if (count == 0)
        return -1;
    
    int best_index=-1, best_size=4096*15*1000;
    int index;

    index = 0;
    while (index < length)
    {
        // 越过已经分配的资源
        while (index < length && get(index))
            ++index;

        // 不存在连续的count个资源
        if (index == length)
            return -1;

        int temp_size=0;   //考虑当前大小，开始计数，并且将当前index暂时保存
        int temp_id=index;
       
        while ((index < length) && (!get(index)))
        {
            ++temp_size;
            ++index;
        }
        
        if(temp_size >= count && temp_size < best_size)
        {
            //更新现在最优解
            best_size=temp_size;
            best_index=temp_id;
        }
        
    }
    
    if(best_index!=-1)
    {
        for(int i=0; i<count; i++)
        {
            set(best_index + i, true);
        }
    }
    return best_index;  //如果没有找到合适的块，best_index会返回-1，否则是一个有意义的值。
}

void BitMap::release(const int index, const int count)
{
    for (int i = 0; i < count; ++i)
    {
        set(index + i, false);
    }
}

char *BitMap::getBitmap()
{
    return (char *)bitmap;
}

int BitMap::size() const
{
    return length;
}
